Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Don't copy imported module to filter out its dependencies #826

Merged
merged 10 commits into from
Dec 20, 2024

Conversation

vsbogd
Copy link
Collaborator

@vsbogd vsbogd commented Dec 19, 2024

This PR is replacement of #776 without issue which were caused by old interpreter implementation. New commits start from 4277146

In this PR ModuleSpace is introduced which keeps main space and its dependencies separately. This allows querying them separately and when dependent space is queried it doesn't queried recursively. Thus all transitive dependencies are queried only once from the top level space.

For example if we have space A which imports space B and C and D is imported from B and C then A contains B, C and D as dependencies in a separate collection. Query to A goes through its atoms first then goes to B, C and D but dependencies of these spaces are not queried.

ModuleSpace::atom_iter() iterates through main atomspace only. This breaks tests in f1_imports.metta which are disabled in this change. There are two ways of solving this: (1) adding dependency spaces as atoms into ModuleSpace iterator which resembles previous behavior, (2) add separate function which gets dependencies from space. I would like to implement solution after discussing a way. Option (2) is not possible with current DynSpace used internally as space representation may be it can be implemented after additional refactoring.

New Space::visit method is added because it is impossible to implement Space::atom_iter for DynSpace safely (see @luketpeterson comment #776 (comment)). Internal usages of Space::atom_iter are replaced by Space::visit usages.

ModuleSpace doesn't keep imported spaces as atoms. It keeps them in a
separate collection instead. This allows constructing new instances of
the ModuleSpace without filtering original imported space.
Space::visit() is safer because it doesn't exposes references to the
atoms which are behind internally mutable smart pointer.
Replacing `&Atom` by `Cow<Atom>` thus allowing passing both reference
and value instance.
Add TODOs for tests which are possible if get-deps function is
implemented.
This implementation has a safety hole. Say the user borrows an iterator
from the space behind a RefCell, then uses the iterator to get
references to some atoms, saves those references, and then drops the
iterator. The user could then use borrow_mut to mutably access the space
and delete those atoms. This would leave the original atom references
pointing to garbage.

Space::visit is implemented instead and all internal iterator usages are
replaced by Space::visit usages.
Copy link
Contributor

@luketpeterson luketpeterson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wholeheartedly approve these changes. :-)

@luketpeterson
Copy link
Contributor

ModuleSpace::atom_iter() iterates through main atomspace only. This breaks tests in f1_imports.metta which are disabled in this change. There are two ways of solving this: (1) adding dependency spaces as atoms into ModuleSpace iterator which resembles previous behavior, (2) add separate function which gets dependencies from space. I would like to implement solution after discussing a way. Option (2) is not possible with current DynSpace used internally as space representation may be it can be implemented after additional refactoring.

As to this question, it gets into the behavior expected from the MeTTa language / modules. I was assuming behavior 1 was "correct", based on how things worked before the module separation was added. But a case can be made for either behavior.

@vsbogd
Copy link
Collaborator Author

vsbogd commented Dec 20, 2024

As to this question, it gets into the behavior expected from the MeTTa language / modules. I was assuming behavior 1 was "correct", based on how things worked before the module separation was added. But a case can be made for either behavior.

Yes, we discussed it with @Necr0x0Der as well. We still can add atomspace which is an atom and at the same time contains functions which are available for execution from the space which contains this atom. Thus one still can do something like "manual import".

Introspection of imported modules is important from my perspective. But it is not critical right now and I hope clarifying this behavior later.

@vsbogd vsbogd merged commit b083e09 into trueagi-io:main Dec 20, 2024
1 check passed
@vsbogd vsbogd deleted the no-module-duplication branch December 20, 2024 03:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants